package ldh.text.controller;

import javafx.application.Platform;
import javafx.scene.control.Tab;
import ldh.text.service.CacheDataService;
import ldh.text.service.CursorDataService;
import ldh.text.util.FileSizeUtil;
import ldh.text.util.ThreadPoolUtil;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.LineNumberFactory;
import org.fxmisc.richtext.StyleClassedTextArea;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.nio.ByteBuffer;

public class DataTab extends Tab {

    private static final Logger LOGGER = LoggerFactory.getLogger(DataTab.class);

    private File file;
    private VirtualizedScrollPane virtualizedScrollPane;
    private StyleClassedTextArea styleClassedTextArea;

    private CursorDataService<ByteBuffer> dataService;
    private volatile boolean isLoad = false;
    private double preYvalue = 0.0;
    private double contentHeight = 0.0;  // 内容高度

    public DataTab(File file) {
        this.file = file;

        initUi();

        initEvent();

    }

    public void loadData() {
        try {
            long fileSize = FileSizeUtil.getFileSize(file.toPath());
            int cacheSize = 10 * 1024 * 1024;
            if (fileSize > cacheSize) { // 大于10M
                dataService = new CacheDataService(file, cacheSize);
            } else {
//                dataService = new FileDataService(file);
            }
            ThreadPoolUtil.submit(()->{
                try {
                    isLoad = true;
                    ByteBuffer data = dataService.loadData(0, cacheSize);
                    String content = new String(data.array(), 0, data.limit(), "utf8");
                    Platform.runLater(()->{
                        styleClassedTextArea.insertText(0, content);
                        isLoad = false;
                    });
                } catch (Exception e) {
                    LOGGER.error("open file error", e);
                }
            });

        } catch (Exception e) {
            LOGGER.error("get file size error!", e);
        }
    }

    private void initUi() {
        this.setText(file.getName());
        styleClassedTextArea = new StyleClassedTextArea();
        styleClassedTextArea.setParagraphGraphicFactory(LineNumberFactory.get(styleClassedTextArea));

        virtualizedScrollPane = new VirtualizedScrollPane(styleClassedTextArea);
        this.setContent(virtualizedScrollPane);
    }

    private void initEvent() {
        this.setOnCloseRequest(e->{
            try {
                dataService.close();
            } catch (Exception exception) {
                LOGGER.error("close dataService error", exception);
            }
        });

//        virtualizedScrollPane.estimatedScrollYProperty().addListener(l->{
//            double data = ((double)virtualizedScrollPane.totalHeightEstimateProperty().getOrElse(0.0)) - virtualizedScrollPane.getEstimatedScrollY();
//
//            double totalHeight = styleClassedTextArea.totalWidthEstimateProperty().getOrElse(Double.MAX_VALUE);
//            if (Double.compare(totalHeight, contentHeight) != 0) {
//                contentHeight = totalHeight;
//                return;
//            }
//
////            LOGGER.info("scroll Y : {}, {}, {}, {}", virtualizedScrollPane.getEstimatedScrollY(), data,
////                    totalHeight, virtualizedScrollPane.getHeight());
//
//            double currentYvalue = styleClassedTextArea.getEstimatedScrollY();
//            if (totalHeight - currentYvalue < 10 && !isLoad && totalHeight >= virtualizedScrollPane.getHeight() && preYvalue < currentYvalue) {
//                LOGGER.info("next {}, {}, {}, {}", totalHeight, preYvalue, currentYvalue, virtualizedScrollPane.getHeight());
//                loadNextData();
//            }
//
//            if (currentYvalue < 10 && !isLoad && totalHeight >= virtualizedScrollPane.getHeight() && preYvalue > currentYvalue) {
//                LOGGER.info("pre {}, {}, {}, {}", totalHeight, preYvalue, currentYvalue, virtualizedScrollPane.getHeight());
////                loadPreData();
//            }
//
//            preYvalue = styleClassedTextArea.getEstimatedScrollY();
//            contentHeight = totalHeight;
//        });
    }

    private void loadPreData() {
        ThreadPoolUtil.submit(()->{
            try {
                LOGGER.info("load pre data");
                isLoad = true;
                int nextSize = 2 * 1024 * 1024;
                ByteBuffer data = dataService.loadPreData(nextSize);
                String content = new String(data.array(), 0, data.limit(), "utf8");
                Platform.runLater(()->{
                    styleClassedTextArea.replaceText(styleClassedTextArea.getText().length()-nextSize, nextSize, "");
                    styleClassedTextArea.insertText(0, content);
                    isLoad = false;
                });
            } catch (Exception e) {
                LOGGER.error("load data error", e);
            }
        });
    }

    private void loadNextData() {
        ThreadPoolUtil.submit(()->{
            try {
                LOGGER.info("load next data");
                isLoad = true;
                int nextSize = 2 * 1024 * 1024;
                ByteBuffer data = dataService.loadNextData(nextSize);
                String content = new String(data.array(), 0, data.limit(), "utf8");
                Platform.runLater(()->{
                    styleClassedTextArea.replaceText(0, nextSize, "");
                    styleClassedTextArea.appendText(content);
                    isLoad = false;
                });
            } catch (Exception e) {
                LOGGER.error("load data error", e);
            }
        });


    }
}
